use thiserror::Error;
use std::sync::Arc;
use std::sync::Mutex;
use super::api;
use super::super::core::types::{CapabilityId, ResourceType};

// 定义能力错误类型
#[derive(Error, Debug)]
pub enum CapabilityError {
    #[error("Capability not acquired")]
    NotAcquired,
    
    #[error("Invalid capability ID")]
    InvalidId,
    
    #[error("Capability already acquired")]
    AlreadyAcquired,
    
    #[error("Permission denied")]
    PermissionDenied,
}

// 定义能力结果类型
pub type CapabilityResult<T> = Result<T, CapabilityError>;

// 能力包装器（安全地管理exokernel能力）
pub struct Capability {
    id: CapabilityId,
    acquired: bool,
    resource_type: ResourceType,
}

impl Capability {
    // 创建新的能力包装器
    pub fn new(id: CapabilityId, resource_type: ResourceType) -> Self {
        Capability {
            id,
            acquired: false,
            resource_type,
        }
    }

    // 获取能力
    pub fn acquire(&mut self) -> CapabilityResult<bool> {
        if !self.acquired {
            let result = unsafe {
                api::exokernel_get_capability(self.id)
            };
            if result {
                self.acquired = true;
                Ok(true)
            } else {
                Err(CapabilityError::NotAcquired)
            }
        } else {
            Ok(true)
        }
    }

    // 释放能力
    pub fn release(&mut self) {
        if self.acquired {
            unsafe {
                api::exokernel_release_capability(self.id);
            }
            self.acquired = false;
        }
    }

    // 获取能力ID
    pub fn id(&self) -> CapabilityId {
        self.id
    }

    // 检查是否已获取
    pub fn is_acquired(&self) -> bool {
        self.acquired
    }
    
    // 获取资源类型
    pub fn resource_type(&self) -> ResourceType {
        self.resource_type
    }
    
    // 安全地获取初始能力
    pub fn get_initial_capabilities() -> (Option<Self>, Option<Self>) {
        let mut mem_cap_id = 0;
        let mut cpu_cap_id = 0;
        
        let success = unsafe {
            api::exokernel_get_initial_capabilities(&mut mem_cap_id, &mut cpu_cap_id)
        };
        
        if success {
            let mem_cap = Self::new(mem_cap_id, ResourceType::Memory);
            let cpu_cap = Self::new(cpu_cap_id, ResourceType::Cpu);
            (Some(mem_cap), Some(cpu_cap))
        } else {
            (None, None)
        }
    }
}

// 实现Drop以确保能力被正确释放
impl Drop for Capability {
    fn drop(&mut self) {
        self.release();
    }
}

// 线程安全的能力包装器
pub type ThreadSafeCapability = Arc<Mutex<Capability>>;

// 创建线程安全的能力包装器
pub fn create_thread_safe_capability(id: CapabilityId, resource_type: ResourceType) -> ThreadSafeCapability {
    Arc::new(Mutex::new(Capability::new(id, resource_type)))
}